﻿using System;
using System.Linq.Expressions;
using System.Threading.Tasks;

using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Counts;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Filters;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Where;

namespace Tszy.Unlimited.Data.AdoNet.Sql.Components
{
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TSource"></typeparam>
    internal class Query<TSource> : QueryBase<TSource>,
       ICloneable,
       IQuery<TSource>,
       IEnumerableQuery<TSource>,
       IEnumerableTaskQuery<TSource>,
       IEnumerableSkipQuery<TSource>,
       IEnumerableSelectQuery<TSource>,
       IThenOrderByQuery<TSource>,
       ISelectEnumerableQuery<TSource>
       where TSource : new()
    {
        #region 字段

        private readonly IExecuteQueryFactory _executeQueryFactory;

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _whereExpressionExecutor = new WhereExpressionExecutor();

        ///// <summary>
        /////
        ///// </summary>
        //protected static readonly IExpressionExecutor _whereOrExpressionExecutor = new WhereOrExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _selectExpressionExecutor = new SelectExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _anyExpressionExecutor = new AnyExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _countExpressionExecutor = new CountExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _sumExpressionExecutor = new SumExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _orderByExpressionExecutor = new OrderByExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _orderByDescendingExpressionExecutor = new OrderByDescendingExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _averageExpressionExecutor = new AverageExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _minExpressionExecutor = new MinExpressionExecutor();

        /// <summary>
        ///
        /// </summary>
        protected static readonly IExpressionExecutor _maxExpressionExecutor = new MaxExpressionExecutor();

        ///// <summary>
        /////
        ///// </summary>
        //protected static readonly IExpressionExecutor _innerJoinExpressionExecutor = new InnerJoinExpressionExecutor();

        ///// <summary>
        /////
        ///// </summary>
        //protected static readonly IExpressionExecutor _leftJoinExpressionExecutor = new LeftJoinExpressionExecutor();

        #endregion 字段

        #region 构造器

        /// <summary>
        /// 构造器。
        /// </summary>
        /// <param name="executeQueryFactory"></param>
        public Query(IExecuteQueryFactory executeQueryFactory)
        {
            _executeQueryFactory = executeQueryFactory;

            Context.EntityType = typeof(TSource);
        }

        #endregion 构造器

        #region Where 函数

        /// <summary>
        ///
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public IEnumerableQuery<TSource> Where(Expression<Func<TSource, bool>> predicate)
        {
            var context = Context.Clone();

            _whereExpressionExecutor.Execute(context, predicate);

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        #endregion Where 函数

        #region Select 函数

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<short> Select(Expression<Func<TSource, short>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<short?> Select(Expression<Func<TSource, short?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<int> Select(Expression<Func<TSource, int>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<int?> Select(Expression<Func<TSource, int?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<long> Select(Expression<Func<TSource, long>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<long?> Select(Expression<Func<TSource, long?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<float> Select(Expression<Func<TSource, float>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<float?> Select(Expression<Func<TSource, float?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<double> Select(Expression<Func<TSource, double>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<double?> Select(Expression<Func<TSource, double?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<decimal> Select(Expression<Func<TSource, decimal>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<decimal?> Select(Expression<Func<TSource, decimal?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<bool> Select(Expression<Func<TSource, bool>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<bool?> Select(Expression<Func<TSource, bool?>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<char> Select(Expression<Func<TSource, char>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<string> Select(Expression<Func<TSource, string>> selector)
        {
            return SelectStringHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<DateTime> Select(Expression<Func<TSource, DateTime>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        public IExecuteQuery<TResult> Select<TResult>(Expression<Func<TSource, TResult>> selector) where TResult : class, new()
        {
            return SelectHandler(selector);
        }

        public IExecuteQuery<object> Select(Expression<Func<TSource, object>> selector)
        {
            return SelectHandler(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        private IExecuteQuery<TResult> SelectHandler<TResult>(Expression<Func<TSource, TResult>> selector) where TResult : new()
        {
            var context = Context.Clone();

            _selectExpressionExecutor.Execute(context, selector);

            Context = context;

            return _executeQueryFactory.Create<TSource, TResult>(this);
            //return new ExecuteQuery<TSource, TResult>(this);
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        private IExecuteQuery<TResult> SelectStringHandler<TResult>(Expression<Func<TSource, TResult>> selector)
        {
            var context = Context.Clone();

            _selectExpressionExecutor.Execute(context, selector);

            Context = context;

            //return new ExecuteQuery<TSource, TResult>(this);
            return _executeQueryFactory.Create<TSource, TResult>(this);
        }

        #endregion Select 函数

        #region Any 函数

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public bool Any()
        {
            var context = Context.Clone();

            _anyExpressionExecutor.Execute(context, null);

            Context = context;

            return Execute<int>() > 0;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public bool Any(Expression<Func<TSource, bool>> predicate)
        {
            var context = Context.Clone();

            _anyExpressionExecutor.Execute(context, predicate);

            Context = context;

            return Execute<int>() > 0;
        }

        #endregion Any 函数

        #region Count 函数

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return Count(null);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public int Count(Expression<Func<TSource, bool>> predicate)
        {
            var context = Context.Clone();

            _countExpressionExecutor.Execute(context, predicate);

            Context = context;

            return Execute<int>();
        }

        #endregion Count 函数

        #region Sum 函数

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public int Sum(Expression<Func<TSource, int>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public int? Sum(Expression<Func<TSource, int?>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public long Sum(Expression<Func<TSource, long>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public long? Sum(Expression<Func<TSource, long?>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double Sum(Expression<Func<TSource, double>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double? Sum(Expression<Func<TSource, double?>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public float Sum(Expression<Func<TSource, float>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public float? Sum(Expression<Func<TSource, float?>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public decimal Sum(Expression<Func<TSource, decimal>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public decimal? Sum(Expression<Func<TSource, decimal?>> selector)
        {
            return ExecuteSum(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        private TResult ExecuteSum<TResult>(Expression<Func<TSource, TResult>> selector)
        {
            var context = Context.Clone();

            _sumExpressionExecutor.Execute(context, selector);

            Context = context;

            return Execute<TResult>();
        }

        #endregion Sum 函数

        #region Average 函数

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double Average(Expression<Func<TSource, int>> selector)
        {
            return ExecuteAverageDouble(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double? Average(Expression<Func<TSource, int?>> selector)
        {
            return ExecuteAverageDouble(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double Average(Expression<Func<TSource, long>> selector)
        {
            return ExecuteAverageDouble(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double? Average(Expression<Func<TSource, long?>> selector)
        {
            return ExecuteAverageDouble(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double Average(Expression<Func<TSource, double>> selector)
        {
            return ExecuteAverage(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public double? Average(Expression<Func<TSource, double?>> selector)
        {
            return ExecuteAverage(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public float Average(Expression<Func<TSource, float>> selector)
        {
            return ExecuteAverage(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public float? Average(Expression<Func<TSource, float?>> selector)
        {
            return ExecuteAverage(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public decimal Average(Expression<Func<TSource, decimal>> selector)
        {
            return ExecuteAverage(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public decimal? Average(Expression<Func<TSource, decimal?>> selector)
        {
            return ExecuteAverage(selector);
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        private TResult ExecuteAverage<TResult>(Expression<Func<TSource, TResult>> selector)
        {
            var context = Context.Clone();

            _averageExpressionExecutor.Execute(context, selector);

            Context = context;

            return Execute<TResult>();
        }

        private double ExecuteAverageDouble<TResult>(Expression<Func<TSource, TResult>> selector)
        {
            var context = Context.Clone();

            _averageExpressionExecutor.Execute(context, selector);

            Context = context;

            return Execute<double>();
        }

        #endregion Average 函数

        #region Min 函数

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        public TResult Min<TResult>(Expression<Func<TSource, TResult>> selector)
        {
            var context = Context.Clone();

            _minExpressionExecutor.Execute(context, selector);

            Context = context;

            return Execute<TResult>();
        }

        #endregion Min 函数

        #region Max 函数

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selector"></param>
        /// <returns></returns>
        public TResult Max<TResult>(Expression<Func<TSource, TResult>> selector)
        {
            var context = Context.Clone();

            _maxExpressionExecutor.Execute(context, selector);

            Context = context;

            return Execute<TResult>();
        }

        #endregion Max 函数

        #region Order By 函数

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public IThenOrderByQuery<TSource> OrderBy<TKey>(Expression<Func<TSource, TKey>> keySelector)
        {
            var context = Context.Clone();

            _orderByExpressionExecutor.Execute(context, keySelector);

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public IThenOrderByQuery<TSource> ThenBy<TKey>(Expression<Func<TSource, TKey>> keySelector)
        {
            var context = Context.Clone();

            _orderByExpressionExecutor.Execute(context, keySelector);

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public IThenOrderByQuery<TSource> OrderByDescending<TKey>(Expression<Func<TSource, TKey>> keySelector)
        {
            var context = Context.Clone();

            _orderByDescendingExpressionExecutor.Execute(context, keySelector);

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public IThenOrderByQuery<TSource> ThenByDescending<TKey>(Expression<Func<TSource, TKey>> keySelector)
        {
            var context = Context.Clone();

            _orderByDescendingExpressionExecutor.Execute(context, keySelector);

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        #endregion Order By 函数

        #region Take 与 Skip 函数

        /// <summary>
        ///
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        IEnumerableTaskQuery<TSource> ITakeQuery<TSource>.Take(int count)
        {
            var context = Context.Clone();

            context.Take = count;

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        IEnumerableSkipQuery<TSource> ISkipQuery<TSource>.Skip(int count)
        {
            var context = Context.Clone();

            context.Skip = count;

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        IEnumerableSelectQuery<TSource> ISkipQuery_1<TSource>.Skip(int count)
        {
            var context = Context.Clone();

            context.Skip = count;

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        IEnumerableSelectQuery<TSource> ITakeQuery_1<TSource>.Take(int count)
        {
            var context = Context.Clone();

            context.Take = count;

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        #endregion Take 与 Skip 函数

        #region Join 函数

        ///// <summary>
        /////
        ///// </summary>
        ///// <typeparam name="TTarget"></typeparam>
        ///// <param name="predicate"></param>
        ///// <returns></returns>
        //public IJoinEnumerableQuery<TSource, TTarget> InnerJoin<TTarget>(Expression<Func<TSource, TTarget, bool>> predicate) where TTarget : new()
        //{
        //    var context = Context.Clone();

        //    InnerExecuteJoin<TTarget>(context, predicate);

        //    return new JoinEnumerableQueryV3<TSource, TTarget>(_dataManager, DatabaseType) { Context = context };
        //}

        ///// <summary>
        /////
        ///// </summary>
        ///// <typeparam name="TTarget"></typeparam>
        ///// <param name="predicate"></param>
        ///// <returns></returns>
        //public IJoinEnumerableQuery<TSource, TTarget> LeftJoin<TTarget>(Expression<Func<TSource, TTarget, bool>> predicate) where TTarget : new()
        //{
        //    var context = Context.Clone();

        //    LeftExecuteJoin<TTarget>(context, predicate);

        //    return new JoinEnumerableQueryV3<TSource, TTarget>(_dataManager, DatabaseType) { Context = context };
        //}

        ///// <summary>
        /////
        ///// </summary>
        ///// <typeparam name="TDbModel"></typeparam>
        ///// <param name="context"></param>
        ///// <param name="expression"></param>
        //internal virtual void InnerExecuteJoin<TDbModel>(ExpressionContext context, Expression expression) where TDbModel : new()
        //{
        //    var dbModel = new TDbModel();

        //    context.AddTable<TDbModel>(/*dbModel*/);

        //    context.JoinTableName = ParameterManager.Instance.GetDtabaseTableName(context, dbModel.GetType());

        //    _innerJoinExpressionExecutor.Execute(context, expression);
        //}

        ///// <summary>
        /////
        ///// </summary>
        ///// <typeparam name="TDbModel"></typeparam>
        ///// <param name="context"></param>
        ///// <param name="expression"></param>
        //internal virtual void LeftExecuteJoin<TDbModel>(ExpressionContext context, Expression expression) where TDbModel : new()
        //{
        //    var dbModel = new TDbModel();

        //    context.AddTable<TDbModel>(/*dbModel*/);

        //    context.JoinTableName = ParameterManager.Instance.GetDtabaseTableName(context, dbModel.GetType());

        //    _leftJoinExpressionExecutor.Execute(context, expression);
        //}

        #endregion Join 函数

        #region IExecuteQuery

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public QueryEnumerableResult<TSource> ToEnumerable()
        {
            return _executeQueryFactory.Create<TSource, TSource>(this).ToEnumerable();
            //return new ExecuteQuery<TSource, TSource>(this).ToEnumerable();
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public async Task<QueryEnumerableResult<TSource>> ToEnumerableAsync()
        {
            return await _executeQueryFactory.Create<TSource, TSource>(this).ToEnumerableAsync();
            //return await new ExecuteQuery<TSource, TSource>(this).ToEnumerableAsync();
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public TSource FirstOrDefault()
        {
            return _executeQueryFactory.Create<TSource, TSource>(this).FirstOrDefault();

            // return new ExecuteQuery<TSource, TSource>(this).FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public async Task<TSource> FirstOrDefaultAsync()
        {
            return await _executeQueryFactory.Create<TSource, TSource>(this).FirstOrDefaultAsync();
            //return await new ExecuteQuery<TSource, TSource>(this).FirstOrDefaultAsync();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public TSource FirstOrDefault(Expression<Func<TSource, bool>> predicate)
        {
            var context = Context.Clone();

            _whereExpressionExecutor.Execute(context, predicate);

            Context = context;

            return FirstOrDefault();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public async Task<TSource> FirstOrDefaultAsync(Expression<Func<TSource, bool>> predicate)
        {
            var context = Context.Clone();

            _whereExpressionExecutor.Execute(context, predicate);

            Context = context;

            return await FirstOrDefaultAsync();
        }

        public virtual T Execute<T>()
        {
            return _executeQueryFactory.Create<TSource, TSource>(this).Execute<T>();
            //return new ExecuteQuery<TSource, TSource>(this).Execute<T>();
        }

        public virtual async Task<T> ExecuteAsync<T>()
        {
            return await _executeQueryFactory.Create<TSource, TSource>(this).ExecuteAsync<T>();
            //return await new ExecuteQuery<TSource, TSource>(this).ExecuteAsync<T>();
        }

        #endregion IExecuteQuery

        #region 设置本次查询的唯一标识

        /// <summary>
        /// 设置本次查询的唯一标识。
        /// </summary>
        /// <param name="identity"></param>
        /// <returns></returns>
        public IQuery<TSource> SetIdentity(string identity)
        {
            var context = Context.Clone();

            context.Identity = identity ?? string.Empty;

            return new Query<TSource>(_executeQueryFactory) { Context = context };
        }

        #endregion 设置本次查询的唯一标识

        #region ToEnumerableQuery

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public IEnumerableQuery<TSource> ToEnumerableQuery()
        {
            return this;
        }

        #endregion ToEnumerableQuery

        #region 克隆

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            throw new NotImplementedException();
        }

        #endregion 克隆
    }

    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TSource"></typeparam>
    public abstract class QueryBase<TSource> where TSource : new()
    {
        #region 构造器

        /// <summary>
        ///
        /// </summary>
        protected QueryBase()
        {
            Context = new ExpressionContext(typeof(TSource));
        }

        #endregion 构造器

        /// <summary>
        ///
        /// </summary>
        public ExpressionContext Context { get; set; }
    }
}